package cn.com.compass.base.convter;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import cn.com.compass.base.em.IBaseBizStatusEnum;


/**
 * 
 * @author wanmk
 * @git https://gitee.com/milkove
 * @email 524623302@qq.com
 * @todo mybatis 枚举转换
 * @date 2018年6月7日 下午3:55:07
 *
 */
public class MybatisDbEnumTypeHandler<E extends IBaseBizStatusEnum> extends BaseTypeHandler<E> {

	private Class<E> type;  
    private E [] enums;  
      
    /** 
     * 设置配置文件设置的转换类以及枚举类内容，供其他方法更便捷高效的实现 
     * @param type 配置文件中设置的转换类 
     */  
    public MybatisDbEnumTypeHandler(Class<E> type) {  
        if (type == null)  
            throw new IllegalArgumentException("Type argument cannot be null");  
        this.type = type;  
        this.enums = type.getEnumConstants();  
        if (this.enums == null)  
            throw new IllegalArgumentException(type.getSimpleName()  
                    + " does not represent an enum type.");  
    }  
      
    @Override  
    public void setNonNullParameter(PreparedStatement ps, int i, E parameter,  
            JdbcType jdbcType) throws SQLException {  
        //BaseTypeHandler已经帮我们做了parameter的null判断  
        ps.setObject(i,parameter.getCode(), jdbcType.TYPE_CODE);   
    }  
  
    @Override  
    public E getNullableResult(ResultSet rs, String columnName)  
            throws SQLException {  
        // 根据数据库存储类型决定获取类型，本例子中数据库中存放Integer类型  
    	Integer i = rs.getInt(columnName);  
        if (rs.wasNull()) {  
            return null;  
        } else {  
            // 根据数据库中的value值，定位PersonType子类  
            return locateEnumStatus(i);  
        }  
    }  
  
    @Override  
    public E getNullableResult(ResultSet rs, int columnIndex)  
            throws SQLException {  
        // 根据数据库存储类型决定获取类型，本例子中数据库中存放Integer类型  
    	Integer i = rs.getInt(columnIndex);  
        if (rs.wasNull()) {  
            return null;  
        } else {  
            // 根据数据库中的value值，定位PersonType子类  
            return locateEnumStatus(i);  
        }  
    }  
  
    @Override  
    public E getNullableResult(CallableStatement cs, int columnIndex)  
            throws SQLException {  
        // 根据数据库存储类型决定获取类型，本例子中数据库中存放Integer类型  
        Integer i = cs.getInt(columnIndex);  
        if (cs.wasNull()) {  
            return null;  
        } else {  
            // 根据数据库中的value值，定位PersonType子类  
            return locateEnumStatus(i);  
        }  
    }  
  
     /** 
     * 枚举类型转换，由于构造函数获取了枚举的子类enums，让遍历更加高效快捷 
     * @param value 数据库中存储的自定义value属性 
     * @return value对应的枚举类 
     */  
    private E locateEnumStatus(Integer value) {  
    	return IBaseBizStatusEnum.fromCode(type, value);
    } 

}
